﻿using Microsoft.Office.Interop.Word;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.XWPF.UserModel;
using Petroleum.DB.Model;
using Petroleum.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;

namespace Petroleum.Tool
{
    public class WordUtil
    {
        string ImagesPath = AppDomain.CurrentDomain.BaseDirectory + "ImagesPath/";

        /// <summary>
        /// 生成word文档参考：https://www.cnblogs.com/duanrantao/p/8682897.html
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="docTemplatePath">doc模板存放路径</param>
        public static void CreateDoc(SessionDynamic data, string docTemplatePath, string newTempletePath)
        {
            if (File.Exists(docTemplatePath))
            {
                string newTempleteFileName = "\\自动化生成文档" + Guid.NewGuid().ToString() + ".docx";
                if (!Directory.Exists(newTempletePath))
                {
                    Directory.CreateDirectory(newTempletePath);
                }
                string newTempleteFullPath = newTempletePath + newTempleteFileName;
                File.Copy(docTemplatePath, newTempleteFullPath);//拷贝doc模板
                FileStream fileStream = new FileStream(newTempleteFullPath, FileMode.Open, FileAccess.Read);
                XWPFDocument myDoc = new XWPFDocument(fileStream);
                //遍历段落，替换内容
                foreach (var para in myDoc.Paragraphs)
                {
                    ReplaceKey(data, para);//文档介绍
                    ReplaceKey(data.BasicInf, para);//文档基础信息
                }
                //遍历table，替换单元格内容
                TableData(myDoc.Tables, data);
                MemoryStream ms = new MemoryStream();
                myDoc.Write(ms);
                //保存修改后的文档
                // 把 byte[] 写入文件 
                FileStream fs = new FileStream(newTempleteFullPath, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(ms.GetBuffer());
                bw.Close();
                fs.Close();
            }
        }
        static void TableData(IList<XWPFTable> tables, SessionDynamic data)
        {
            //遍历table，替换单元格内容
            foreach (var table in tables)
            {
                foreach (var row in table.Rows)
                {
                    foreach (var cell in row.GetTableCells())
                    {
                        foreach (var para in cell.Paragraphs)
                        {
                            ReplaceKey(data, para);//文档介绍
                            ReplaceKey(data.BasicInf, para);//1文档基础信息
                            ReplaceKey(data.FormationPressure, para);//2底层压力测试 图片
                            ReplaceKey(data.FormationPressure, para);//2底层压力测试 图片
                        }
                    }
                }
            }
        }
        static void InsertTable(IList<XWPFTable> tables, SessionDynamic data)
        {
            for (int i = 0; i < data.FormationPressure.list.Count; i++)
            {
                foreach (var table in tables)
                {
                    string a = table.Text;
                    if (a.StartsWith("Prognoses of Well"))
                    {
                        if (i > 0)
                        {
                            ReplaceKeyCell(data.FormationPressure.list[i], table);
                        }
                        else
                        {
                            foreach (var row in table.Rows)
                            {
                                foreach (var cell in row.GetTableCells())
                                {
                                    foreach (var para in cell.Paragraphs)
                                    {
                                        ReplaceKey(data.FormationPressure.list[i], para);//2底层压力测试 图片
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        private static void ReplaceKeyCell<T>(T etity, XWPFTable table)//自动添加行
        {
            CT_Row nr = new CT_Row();
            XWPFTableRow mr = new XWPFTableRow(nr, table);//创建行 
            table.AddRow(mr);//将行添加到table中 
            Type entityType = etity.GetType();
            PropertyInfo[] properties = entityType.GetProperties();
            foreach (var p in properties)
            {
                try
                {
                    object value = p.GetValue(etity);
                    if (value == null)
                    {
                        value = "";
                        continue;
                    }
                    XWPFTableCell cell = mr.AddNewTableCell();
                    XWPFParagraph para = cell.AddParagraph();
                    XWPFRun run = para.CreateRun();
                    if (p.Name.ToLower().Contains("img"))
                    {
                        var widthEmus = (int)(400.0 * 9525);
                        var heightEmus = (int)(300.0 * 9525);
                        using (FileStream picData = new FileStream(@"G:\WordFiles\" + value.ToString(), FileMode.Open, FileAccess.Read))
                        {
                            run.AddPicture(picData, (int)PictureType.PNG, value.ToString(), widthEmus, heightEmus);
                        }
                    }
                    else
                        run.SetText(value.ToString());
                }
                catch (Exception ex)
                {
                }
            }
        }
        /// <summary>
        /// word模板内容替换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="etity">实体数据</param>
        /// <param name="para">段落</param>
        private static void ReplaceKey<T>(T etity, XWPFParagraph para, int j = 0)
        {
            Type entityType = etity.GetType();
            PropertyInfo[] properties = entityType.GetProperties();
            //string entityName = entityType.Name;//实体类名称
            string paratext = para.ParagraphText;
            var runs = para.Runs;
            string styleid = para.Style;
            string text = paratext;
            if (text == "")
            {
                return;
            }
            foreach (var p in properties)
            {
                string propteryName = j == 0 ? "{$" + p.Name + "}" : "{$" + p.Name + j + "}";//Word模板中设定的需要替换的标签
                try
                {
                    object value = p.GetValue(etity);
                    if (value == null)
                    {
                        value = "";
                    }
                    if (text.Contains(propteryName))
                    {
                        if (propteryName.ToLower().Contains(j == 0 ? "img" : "img" + j))
                        {
                            //var img = Image.FromFile(@"G:\WordFiles\" + p.Name);
                            var widthEmus = (int)(400.0 * 9525);
                            var heightEmus = (int)(300.0 * 9525);
                            using (FileStream picData = new FileStream(@"G:\WordFiles\" + value.ToString(), FileMode.Open, FileAccess.Read))
                            {
                                XWPFRun r2 = para.CreateRun();
                                r2.AddPicture(picData, (int)PictureType.PNG, value.ToString(), widthEmus, heightEmus);
                                para.ReplaceText(propteryName, "");//替换图片标签为空（重要）
                            }
                        }
                        else
                            para.ReplaceText(propteryName, value.ToString());//替换标签文本（重要）
                    }
                }
                catch (Exception ex)
                {
                }
            }
        }
        #region 抛弃昨天的自己，放弃明天的你，今天的你还剩下什么？

        /// <summary>
        /// 生成word文档
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="docTemplatePath">doc模板存放路径</param>
        public static void CreateDocP(SessionDynamic data, string docTemplatePath)
        {
            if (File.Exists(docTemplatePath))
            {
                string newTempletePath = "D:\\WordFiles\\";
                string newTempleteFileName = Guid.NewGuid().ToString() + ".docx";
                if (!Directory.Exists(newTempletePath))
                {
                    Directory.CreateDirectory(newTempletePath);
                }
                string newTempleteFullPath = newTempletePath + newTempleteFileName;
                File.Copy(docTemplatePath, newTempleteFullPath);//拷贝doc模板
                                                                //读取Word模板
                FileStream fileStream = new FileStream(newTempleteFullPath, FileMode.Open, FileAccess.Read);
                XWPFDocument myDoc = new XWPFDocument(fileStream);

                //遍历段落，替换内容
                foreach (var para in myDoc.Paragraphs)
                {
                    ReplaceKey(data, para);
                    //ReplaceKey(data.BasicInf, para);
                    //ReplaceKey(data.FormationPressure, para);

                    //ReplaceKey(data.CasingProgram, para);
                    //ReplaceKey(data.ProgresPlanList, para);

                }
                //遍历table，替换单元格内容
                foreach (var table in myDoc.Tables)
                {
                    foreach (var row in table.Rows)
                    {
                        foreach (var cell in row.GetTableCells())
                        {
                            foreach (var para in cell.Paragraphs)
                            {
                                ReplaceKey(data, para);
                                //ReplaceKey(data.BasicInf, para);
                                //ReplaceKey(data.FormationPressure, para);

                                //ReplaceKey(data.CasingProgram, para);
                                //ReplaceKey(data.ProgresPlanList, para);
                            }
                        }
                    }
                }
                MemoryStream ms = new MemoryStream();
                myDoc.Write(ms);
                //保存修改后的文档
                // 把 byte[] 写入文件 
                FileStream fs = new FileStream("D:\\newDoctest.docx", FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(ms.GetBuffer());
                bw.Close();
                fs.Close();
            }
        }

        /// <summary>
        /// 生成word文档参考：https://www.cnblogs.com/duanrantao/p/8682897.html
        /// </summary>
        /// <param name="userInfo">用户信息</param>
        /// <param name="docTemplatePath">doc模板存放路径</param>
        public static void CreateDoc1(SessionDynamic data, string docTemplatePath, string newTempletePath)
        {
            if (File.Exists(docTemplatePath))
            {
                string newTempleteFileName = "\\自动化生成文档" + Guid.NewGuid().ToString() + ".docx";
                if (!Directory.Exists(newTempletePath))
                {
                    Directory.CreateDirectory(newTempletePath);
                }
                string newTempleteFullPath = newTempletePath + newTempleteFileName;
                File.Copy(docTemplatePath, newTempleteFullPath);//拷贝doc模板
                                                                //读取Word模板
                FileStream fileStream = new FileStream(newTempleteFullPath, FileMode.Open, FileAccess.Read);
                XWPFDocument myDoc = new XWPFDocument(fileStream);

                //遍历段落，替换内容
                foreach (var para in myDoc.Paragraphs)
                {
                    ReplaceKey(data, para);
                    ReplaceKey(data.BasicInf, para);
                    ReplaceKey(data.FormationPressure, para);
                    ReplaceKey(data.CasingProgram, para);
                    ReplaceKey(data.ProgresPlanList, para);
                }
                //遍历table，替换单元格内容
                foreach (var table in myDoc.Tables)
                {
                    foreach (var row in table.Rows)
                    {
                        foreach (var cell in row.GetTableCells())
                        {
                            foreach (var para in cell.Paragraphs)
                            {
                                ReplaceKey(data, para);
                                ReplaceKey(data.BasicInf, para);
                                ReplaceKey(data.FormationPressure, para);
                                ReplaceKey(data.CasingProgram, para);
                                ReplaceKey(data.ProgresPlanList, para);
                            }
                        }
                    }
                }
                MemoryStream ms = new MemoryStream();
                myDoc.Write(ms);
                //保存修改后的文档
                // 把 byte[] 写入文件 
                FileStream fs = new FileStream(newTempleteFullPath, FileMode.Create);
                BinaryWriter bw = new BinaryWriter(fs);
                bw.Write(ms.GetBuffer());
                bw.Close();
                fs.Close();
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="filePath"></param> Word地址
        /// <param name="oldStr"></param> 书签
        /// <param name="newStr"></param>  新文字或者图片地址
        /// <param name="type"></param>  类型
        public void testimg(string filePath, string oldStr, string newStr, string type)
        {


            object Nothing = System.Reflection.Missing.Value;
            //创建一个名为wordApp的组件对象
            Microsoft.Office.Interop.Word.Application wordApp = new Microsoft.Office.Interop.Word.Application();

            //word文档位置
            object filename = filePath;

            //定义该插入图片是否为外部链接
            object linkToFile = true;

            //定义插入图片是否随word文档一起保存
            object saveWithDocument = true;

            //打开word文档
            Microsoft.Office.Interop.Word.Document doc = wordApp.Documents.Open(ref filename, ref Nothing, ref Nothing, ref Nothing,
               ref Nothing, ref Nothing, ref Nothing, ref Nothing,
               ref Nothing, ref Nothing, ref Nothing, ref Nothing,
               ref Nothing, ref Nothing, ref Nothing, ref Nothing);
            try
            {
                //书签
                object bookMark = oldStr;
                //图片或文字
                string replacePic = newStr;
                //书签是否存在
                if (doc.Bookmarks.Exists(Convert.ToString(bookMark)) == true)
                {
                    //查找书签
                    doc.Bookmarks.get_Item(ref bookMark).Select();
                    //是图片还是文字
                    if (type.Equals("img"))
                    {
                        //设置图片位置
                        wordApp.Selection.ParagraphFormat.Alignment = Microsoft.Office.Interop.Word.WdParagraphAlignment.wdAlignParagraphRight;
                        //在书签的位置添加图片
                        InlineShape inlineShape = wordApp.Selection.InlineShapes.AddPicture(replacePic, ref linkToFile, ref saveWithDocument, ref Nothing);
                        wordApp.Selection.InlineShapes.AddPicture(replacePic, ref linkToFile, ref saveWithDocument, ref Nothing);
                        //设置图片大小
                        inlineShape.Width = 300;
                        inlineShape.Height = 300;
                    }
                    else
                    {
                        //文字就直接替换
                        wordApp.Selection.Text = replacePic;
                    }

                    doc.Save();
                    doc.Close(ref Nothing, ref Nothing, ref Nothing);
                    wordApp.Quit(ref Nothing, ref Nothing, ref Nothing);
                }
                else
                {
                    //word文档中不存在该书签，关闭文档
                    doc.Close(ref Nothing, ref Nothing, ref Nothing);
                }
            }
            catch
            {
            }
        }

        /// <summary>
        /// word模板内容替换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="etity">实体数据</param>
        /// <param name="para">段落</param>
        private static void ReplaceKeyPlus<T>(T etity, XWPFParagraph para)
        {
            Type entityType = typeof(T);
            PropertyInfo[] properties = entityType.GetProperties();

            string entityName = entityType.Name;//实体类名称
            string paratext = para.ParagraphText;
            var runs = para.Runs;
            string styleid = para.Style;
            string text = "";
            foreach (var run in runs)
            {
                text = run.ToString();
                foreach (var p in properties)
                {
                    string propteryName = "{$" + p.Name + "}";//Word模板中设定的需要替换的标签
                                                              //if (propteryName.Contains("Img"))//Word模板中设定的需要替换的图片
                                                              //{

                    //}

                    object value = p.GetValue(etity);
                    if (value == null)
                    {
                        value = "";
                    }
                    if (text.Contains(propteryName))
                    {
                        text = text.Replace(propteryName, value.ToString());
                    }
                    run.SetText(text);//替换标签文本（重要）
                }
            }
        }

        /// <summary>
        /// word模板内容替换
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="etity">实体数据</param>
        /// <param name="para">段落</param>
        private static void ReplaceKey1<T>(T etity, XWPFParagraph para)
        {
            Type entityType = typeof(T);
            PropertyInfo[] properties = entityType.GetProperties();
            string entityName = entityType.Name;//实体类名称
            string paratext = para.ParagraphText;
            var runs = para.Runs;
            string styleid = para.Style;
            string text = "";
            foreach (var run in runs)
            {
                text = run.ToString();
                foreach (var p in properties)
                {
                    string propteryName = "{$" + p.Name + "$}";//Word模板中设定的需要替换的标签
                    try
                    {
                        object value = p.GetValue(etity);
                        if (value == null)
                        {
                            value = "";
                        }
                        if (text.Contains(propteryName))
                        {
                            LogHelper.WriteLog($"替换文本:===={ text}为{ p.Name}");
                            text = text.Replace(propteryName, value.ToString());
                        }
                        run.SetText(text);//替换标签文本（重要）
                    }
                    catch (Exception ex)
                    {
                        LogHelper.WriteLog("参数计数不匹配" + ex.Message);
                    }
                }
            }
        }
        #endregion
    }
}
